﻿using ITSM.Model;
using ITSM.Model.Entity;
using ITSM.Model.Model;
using Microsoft.Extensions.Logging;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ITSM.Service
{
    public class Demand : BaseDB, IDemand
    {
        private readonly ILogger _log;
        private readonly IWxMessage _wxMessage;
        private readonly IKnowledgeBase _knowledgeBase;

        public Demand(ILogger<Demand> log, IWxMessage wxMessage, IKnowledgeBase knowledgeBase)
        {
            _log = log;
            _wxMessage = wxMessage;
            _knowledgeBase = knowledgeBase;
        }

        public List<M_DemandLevel> GetDemandLevels()
        {
            try
            {
                return db.Queryable<RYD_FieldDict>().Where(res => res.RYD_FieldName == "DemandTypeLevel" && res.RYD_State == 1).Select(res => new M_DemandLevel { RYD_DemandLevelName = res.RYD_FieldText, RYD_DemandLevelNo = res.RYD_FieldValue }).OrderBy(res => res.RYD_DemandLevelNo).ToList();
            }
            catch (Exception e)
            {
                _log.LogError("获取事件重要级别错误！{e}", e);
                return new List<M_DemandLevel>();
            }
        }

        public string AddDemand(M_Demand demand)
        {
            try
            {
                List<RYD_DemandTypeLink> typeLinks = db.Queryable<RYD_DemandTypeLink, RYD_UserInfo>((res, us) => res.RYD_UserId == us.RYD_Id)
                    .Where((res, us) =>
                        (res.RYD_Company == demand.RYD_Company||us.AcrossCompanies==1)
                        && res.RYD_DemandTypeNo == demand.RYD_TypeId
                        && us.RYD_IsDelete == 1
                        && (us.RYD_State == 2 || (us.RYD_State == 4 && !string.IsNullOrWhiteSpace(us.RYD_Name)))
                    ).Select((res, us) => res).ToList();

                if (typeLinks.Count <= 0)
                {
                    return "";
                }
                string userId = AssignPersonnel(typeLinks);
                if (string.IsNullOrWhiteSpace(userId))
                {
                    return "";
                }

                RYD_DemandList rYD_Demand = new()
                {
                    RYD_UserId = demand.RYD_UserId,
                    RYD_Id = Guid.NewGuid().ToString(),
                    RYD_Company = demand.RYD_Company,
                    RYD_Level = demand.RYD_Level,
                    RYD_State = 1,
                    RYD_TypeId = demand.RYD_TypeId,
                    RYD_ItId = userId,
                    RYD_UserStartTime = DateTime.Now,
                    RYD_DemandDetails = demand.RYD_DemandDetails,
                    RYD_Files = demand.RYD_Files,
                    RYD_UserName = demand.RYD_UserName,
                    RYD_UserPhone = demand.RYD_UserPhone,
                    RYD_UserAddress = demand.RYD_UserAddress,
                    RYD_UserIp = demand.RYD_UserIp,
                    RYD_CreateTime = DateTime.Now,
                    RYD_CreateBy = demand.RYD_UserId
                };
                rYD_Demand = db.Insertable(rYD_Demand).ExecuteReturnEntity();
                if (rYD_Demand != null)
                {
                    try
                    {
                        string wxNo = db.Queryable<RYD_UserInfo>().Where(res => res.RYD_Id == rYD_Demand.RYD_UserId && res.RYD_IsDelete == 1).First().RYD_WxNo;
                        string urlStart = AppHelper.ReadAppSettings("wxUrlStart");
                        string urlEnd = AppHelper.ReadAppSettings("wxUrlEnd");
                        string typeName = db.Queryable<RYD_DemandType>().Where(res => res.RYD_DemandTypeNo == rYD_Demand.RYD_TypeId).First().RYD_DemandTypeName;
                        string itName = db.Queryable<RYD_UserInfo>().Where(res => res.RYD_Id == rYD_Demand.RYD_ItId).First().RYD_Name;
                        string levelName = db.Queryable<RYD_FieldDict>().Where(res => res.RYD_FieldName == "DemandTypeLevel" && res.RYD_FieldValue == rYD_Demand.RYD_Level.ToString()).First().RYD_FieldText;
                        M_Template template = new()
                        {
                            client_msg_id = DateTimeOffset.Now.ToFileTime().ToString(),
                            touser = wxNo,
                            url = urlStart + "RYD_DemandId=" + rYD_Demand.RYD_DemandId + urlEnd,
                            data = new M_Template.Data()
                            {
                                first = new M_Template.valueColor()
                                {
                                    value = "下单成功提醒！"
                                },
                                keyword1 = new M_Template.valueColor()
                                {
                                    value = "下单时间：" + DateTime.Now.ToString("yyyy-MM-dd HH:mm")
                                },
                                keyword2 = new M_Template.valueColor()
                                {
                                    value = "订单单号:\t" + rYD_Demand.RYD_DemandId +
                                                "\n类别:\t" + typeName +
                                                "\nIT负责人:\t" + itName +
                                                "\n申请人:\t" + rYD_Demand.RYD_UserName +
                                                "\n事件等级:\t" + levelName
                                },
                                remark = new M_Template.valueColor()
                                {
                                    value = "请耐心等待IT人员接单！"
                                }
                            }
                        };
                        _wxMessage.SendMessage(template);
                        wxNo = db.Queryable<RYD_UserInfo>().Where(res => res.RYD_Id == rYD_Demand.RYD_ItId && res.RYD_IsDelete == 1).First().RYD_WxNo;
                        template = new M_Template()
                        {
                            state = rYD_Demand.RYD_State ?? 0,
                            demandId = rYD_Demand.RYD_DemandId,
                            client_msg_id = DateTimeOffset.Now.ToFileTime().ToString(),
                            touser = wxNo,
                            url = urlStart + "RYD_DemandId=" + rYD_Demand.RYD_DemandId + urlEnd,
                            data = new M_Template.Data()
                            {
                                first = new M_Template.valueColor()
                                {
                                    value = "新订单通知！"
                                },
                                keyword1 = new M_Template.valueColor()
                                {
                                    value = "下单时间：" + DateTime.Now.ToString("yyyy-MM-dd HH:mm")
                                },
                                keyword2 = new M_Template.valueColor()
                                {
                                    value = "订单单号:\t" + rYD_Demand.RYD_DemandId +
                                                "\n类别:\t" + typeName +
                                                "\nIT负责人:\t" + itName +
                                                "\n申请人:\t" + rYD_Demand.RYD_UserName +
                                                "\n事件等级:\t" + levelName
                                },
                                remark = new M_Template.valueColor()
                                {
                                    value = "请IT人员尽快接单处理！"
                                }
                            }
                        };
                        _wxMessage.SendMessage(template);
                        QuartzNetJob.QuartzHelper q = new();
                        int minutes = 15;
                        var levelMinutes = db.Queryable<RYD_FieldDict>().Where(res => res.RYD_FieldName == "DemandTypeLevel" && res.RYD_FieldValue == rYD_Demand.RYD_Level.ToString() && res.RYD_State == 1).ToList().FirstOrDefault();
                        if (levelMinutes != null)
                        {
                            minutes = Convert.ToInt32(levelMinutes.RYD_Remark);
                        }
                        q.SetIntervalJob<JobWork.JobSendMessage>(minutes, template, rYD_Demand.RYD_DemandId + "");


                    }
                    catch (Exception)
                    {
                    }
                    return userId;
                }
                return "";
            }
            catch (Exception)
            {
                return "";
            }

        }

        public string AssignPersonnel(List<RYD_DemandTypeLink> typeLinks)
        {
            if (typeLinks.Count == 1)
            {
                return typeLinks[0].RYD_UserId;
            }
            var keyValuePairs = GetUserState(typeLinks);
            if (keyValuePairs == null)
            {
                return "";
            }
            var keyValueOrderBy = keyValuePairs.OrderBy(res => res.Num).ThenBy(res => res.Level).ThenBy(res => res.Sum).FirstOrDefault();

            if (keyValueOrderBy != null)
            {
                return keyValueOrderBy.RYD_UserId;
            }

            return "";
        }

        public List<M_TransferOrdersUsers>? GetUserState(List<RYD_DemandTypeLink> typeLinks)
        {
            List<string> itIds = new();
            foreach (var item in typeLinks)
            {
                if (!itIds.Contains(item.RYD_UserId))
                {
                    itIds.Add(item.RYD_UserId);
                }
            }
            if (itIds.Count <= 0)
            {
                return null;
            }
            itIds = db.Queryable<RYD_UserInfo>().Where(res => itIds.Contains(res.RYD_Id) && res.RYD_IsDelete == 1 && (res.RYD_State == 2||(res.RYD_State==4&&!string.IsNullOrWhiteSpace(res.RYD_Name)))).Select(res => res.RYD_Id).ToList();
            if (itIds.Count <= 0)
            {
                return null;
            }
            List<M_DemandNum> demandNums = db.Queryable<RYD_DemandList>()
                .Where(res => res.RYD_State > -1 && ((itIds.Contains(res.RYD_ItId) && res.RYD_ToItId == null) || itIds.Contains(res.RYD_ToItId)))
                .GroupBy(res => new { res.RYD_ItId, res.RYD_ToItId, res.RYD_State })
                .Select(res => new M_DemandNum
                { RYD_UserId = res.RYD_ItId, RYD_ToUserId = res.RYD_ToItId, State = res.RYD_State ?? 0, Num = SqlFunc.AggregateCount(res.RYD_ItId) })
                .ToList();
            //a = db.Queryable<RYD_DemandList>().Where(res => itIds.Contains(res.RYD_ToItId) && res.RYD_State > -1).ToList();

            //a = db.Queryable<RYD_DemandList>().Where(res => itIds.Contains(res.RYD_ItId) && (res.RYD_State == 1 || res.RYD_State == 2) && res.RYD_ToItId != null).ToList();
            //a = db.Queryable<RYD_DemandList>().Where(res => itIds.Contains(res.RYD_ToItId) && (res.RYD_State == 1 || res.RYD_State == 2) && res.RYD_State > -1).ToList();

            List<M_TransferOrdersUsers> keyValuePairs = new();
            foreach (var item in typeLinks)
            {
                if (!keyValuePairs.Where(res => res.RYD_UserId == item.RYD_UserId).Any())
                {
                    M_TransferOrdersUsers list = new()
                    {
                        RYD_UserId = item.RYD_UserId,
                        Sum = 0,
                        Num = 0
                    };
                    keyValuePairs.Add(list);
                }
            }
            foreach (var item in demandNums)
            {
                int num = 0;
                int sum = 0;
                if (item.State == 1 || item.State == 2)
                {
                    num += item.Num;
                }
                sum += item.Num;
                var list = keyValuePairs.SingleOrDefault(res => (res.RYD_UserId == item.RYD_UserId && item.RYD_ToUserId == null) || (res.RYD_UserId == item.RYD_ToUserId));
                if (list != null)
                {
                    list.Sum += sum;
                    list.Num += num;
                }
                else
                {
                    list = new()
                    {
                        RYD_UserId = item.RYD_UserId,
                        Sum = sum,
                        Num = num
                    };
                    keyValuePairs.Add(list);
                }
            }
            foreach (var item in keyValuePairs)
            {
                item.RYD_UserName = db.Queryable<RYD_UserInfo>().Where(res => res.RYD_Id == item.RYD_UserId).First().RYD_Name;
                item.Level = db.Queryable<RYD_UserInfo>().Where(res => res.RYD_Id == item.RYD_UserId).First().RYD_Level ?? 0;
            }
            return keyValuePairs;
        }

        public int[] DemandNum(M_DemandList demandList)
        {
            try
            {
                string did = demandList.RYD_DemandId == 0 ? "" : demandList.RYD_DemandId.ToString();
                var list = db.Queryable<RYD_DemandList>()
                    .Where(res => res.RYD_UserName.Contains(demandList.RYD_UserName ?? "") && res.RYD_DemandId.ToString().Contains(did)
                    && res.RYD_Company == demandList.RYD_Company
                    && ((res.RYD_State > 0 && res.RYD_State < 4
                    && (
                        (res.RYD_ItId == demandList.RYD_UserId && res.RYD_ToItId == null) || res.RYD_ToItId == demandList.RYD_UserId || res.RYD_UserId == demandList.RYD_UserId
                    )) || (res.RYD_State == -2 && res.RYD_UserId == demandList.RYD_UserId))
                    ).GroupBy(res => res.RYD_State).Select(res => new { res.RYD_State, num = SqlFunc.AggregateCount(res.RYD_State) }).ToList();
                var a = list.Where(res => res.RYD_State == 1).FirstOrDefault();
                int num1 = 0;
                if (a != null)
                {
                    num1 = a.num;
                }
                a = list.Where(res => res.RYD_State == 2).FirstOrDefault();
                int num2 = 0;
                if (a != null)
                {
                    num2 = a.num;
                }
                a = list.Where(res => res.RYD_State == 3).FirstOrDefault();
                int num3 = 0;
                if (a != null)
                {
                    num3 = a.num;
                }
                a = list.Where(res => res.RYD_State == -2).FirstOrDefault();
                int num_2 = 0;
                if (a != null)
                {
                    num_2 = a.num;
                }
                return new int[] { num1, num2, num3, num_2 };
            }
            catch (Exception)
            {
                return new int[] { 0, 0, 0, 0 };
            }
        }

        public M_DemandList DemandList(M_DemandList demandList)
        {
#pragma warning disable CS8604 // 引用类型参数可能为 null。
#pragma warning disable IDE0075 // 简化条件表达式
            var exp = Expressionable.Create<RYD_DemandList, RYD_UserInfo, RYD_DemandType>()
                .And((RYD_DemandList, RYD_UserInfo, RYD_DemandType) => RYD_DemandList.RYD_State != -1)
                .AndIF(!string.IsNullOrWhiteSpace(demandList.RYD_UserId) && !demandList.RYD_State.Contains("-2"), (RYD_DemandList, RYD_UserInfo, RYD_DemandType) =>
                (
                    (RYD_DemandList.RYD_ItId == demandList.RYD_UserId && RYD_DemandList.RYD_ToItId == null)
                    || RYD_DemandList.RYD_ToItId == demandList.RYD_UserId
                    || RYD_DemandList.RYD_UserId == demandList.RYD_UserId
                )).AndIF(!string.IsNullOrWhiteSpace(demandList.RYD_UserId) && demandList.RYD_State.Contains("-2"), (RYD_DemandList, RYD_UserInfo, RYD_DemandType) =>
                (
                    RYD_DemandList.RYD_UserId == demandList.RYD_UserId
                ))
                .AndIF(demandList.RYD_State != null ? demandList.RYD_State.Length != 0 : false, (RYD_DemandList, RYD_UserInfo, RYD_DemandType) =>
                (
                    demandList.RYD_State.Contains(RYD_DemandList.RYD_State + "")
                ))
                .AndIF(demandList.RYD_TypeId != null ? demandList.RYD_TypeId.Length != 0 : false, (RYD_DemandList, RYD_UserInfo, RYD_DemandType) =>
                (
                    demandList.RYD_TypeId.Contains(RYD_DemandList.RYD_TypeId + "")
                ))
                .AndIF(demandList.RYD_Level != null ? demandList.RYD_Level.Length != 0 : false, (RYD_DemandList, RYD_UserInfo, RYD_DemandType) =>
                (
                    demandList.RYD_Level.Contains(RYD_DemandList.RYD_Level + "")
                ))
                .AndIF(!string.IsNullOrWhiteSpace(demandList.RYD_Company), (RYD_DemandList, RYD_UserInfo, RYD_DemandType) =>
                (
                    RYD_DemandList.RYD_Company == demandList.RYD_Company
                ))
                .AndIF(demandList.RYD_DemandId != 0, (RYD_DemandList, RYD_UserInfo, RYD_DemandType) =>
                (
                    (RYD_DemandList.RYD_DemandId.ToString()).Contains(demandList.RYD_DemandId.ToString())
                ))
                .AndIF(!string.IsNullOrWhiteSpace(demandList.RYD_UserName), (RYD_DemandList, RYD_UserInfo, RYD_DemandType) =>
                (
                    RYD_DemandList.RYD_UserName.Contains(demandList.RYD_UserName)
                ))
                .And((RYD_DemandList, RYD_UserInfo, RYD_DemandType) =>
                (
                    RYD_DemandList.RYD_UserStartTime >= demandList.StartDateTime
                    && RYD_DemandList.RYD_UserStartTime < demandList.EndDateTime
                ));
#pragma warning restore IDE0075 // 简化条件表达式
#pragma warning restore CS8604 // 引用类型参数可能为 null。
            string orderby = " " + demandList.SortField + " " + demandList.SortFun + " ";
            if (string.IsNullOrWhiteSpace(orderby))
            {
                orderby = " RYD_DemandList.RYD_CreateTime desc";
            }
            var cel = db.Queryable<RYD_DemandList, RYD_UserInfo, RYD_DemandType>(
                (RYD_DemandList, RYD_UserInfo, RYD_DemandType) =>
                    (
                        (RYD_DemandList.RYD_ItId == RYD_UserInfo.RYD_Id && RYD_DemandList.RYD_ToItId == null)
                        || RYD_DemandList.RYD_ToItId == RYD_UserInfo.RYD_Id
                    )
                    && RYD_DemandList.RYD_TypeId == RYD_DemandType.RYD_DemandTypeNo
                )
               .Where(exp.ToExpression())
               .OrderBy(orderby.ToSqlFilter());

            List<M_DemandListData> list = cel.Select<M_DemandListData>()
               //.Select((RYD_DemandList, RYD_UserInfo, RYD_DemandType) => new M_DemandListData()
               //{
               //    RYD_Company = RYD_DemandList.RYD_Company,
               //    RYD_DemandId = RYD_DemandList.RYD_DemandId,
               //    RYD_UserId = RYD_DemandList.RYD_UserId,
               //    RYD_DemandTypeName = RYD_DemandType.RYD_DemandTypeName,
               //    RYD_DemandDetails = RYD_DemandList.RYD_DemandDetails,
               //    RYD_Evaluate = RYD_DemandList.RYD_Evaluate,
               //    RYD_Files = RYD_DemandList.RYD_Files,
               //    RYD_ItEndTime = RYD_DemandList.RYD_ItEndTime,
               //    RYD_ItId = RYD_DemandList.RYD_ItId,
               //    RYD_ItStartTime = RYD_DemandList.RYD_ItStartTime,
               //    RYD_KBId = RYD_DemandList.RYD_KBId,
               //    RYD_Level = RYD_DemandList.RYD_Level,
               //    RYD_Name = RYD_UserInfo.RYD_Name,
               //    RYD_Phone = RYD_UserInfo.RYD_Phone,
               //    RYD_Reason = RYD_DemandList.RYD_Reason,
               //    RYD_Solution = RYD_DemandList.RYD_Solution,
               //    RYD_Star = RYD_DemandList.RYD_Star,
               //    RYD_State = RYD_DemandList.RYD_State,
               //    RYD_UserName = RYD_DemandList.RYD_UserName,
               //    RYD_UserIp = RYD_DemandList.RYD_UserIp,
               //    RYD_ToItId = RYD_DemandList.RYD_ToItId,
               //    RYD_UserAddress = RYD_DemandList.RYD_UserAddress,
               //    RYD_UserEndTime = RYD_DemandList.RYD_UserEndTime,
               //    RYD_UserPhone = RYD_DemandList.RYD_UserPhone,
               //    RYD_UserStartTime = RYD_DemandList.RYD_UserStartTime
               //})
               .Skip((demandList.Page - 1) * demandList.Size)
               .Take(demandList.Size).ToList();
            foreach (var item in list)
            {
                if (item.RYD_ToItId != null)
                {
                    var itemuserinfo = db.Queryable<RYD_UserInfo>().Where(res => res.RYD_Id == item.RYD_ItId).First();
                    item.RYD_OldItName = itemuserinfo.RYD_Name;
                    item.RYD_OldItPhone = itemuserinfo.RYD_Phone;
                }
            }

            demandList.DemandList = list;
            demandList.Sum = cel.Count();

            return demandList;
        }

        public M_DemandInfo DemandInfo(int RYD_DemandId)
        {
            try
            {
                var exp = Expressionable.Create<RYD_DemandList, RYD_UserInfo, RYD_DemandType>()
                    .AndIF(RYD_DemandId != 0, (RYD_DemandList, RYD_UserInfo, RYD_DemandType) =>
                        RYD_DemandList.RYD_DemandId == RYD_DemandId
                    );
                var list = db.Queryable<RYD_DemandList, RYD_UserInfo, RYD_DemandType>(
                    (RYD_DemandList, RYD_UserInfo, RYD_DemandType) =>
                        (
                            (RYD_DemandList.RYD_ItId == RYD_UserInfo.RYD_Id && RYD_DemandList.RYD_ToItId == null)
                            || RYD_DemandList.RYD_ToItId == RYD_UserInfo.RYD_Id
                        )
                        && RYD_DemandList.RYD_TypeId == RYD_DemandType.RYD_DemandTypeNo
                    ).Where(exp.ToExpression());
                //使用Lambda解析速度太慢，所以将Lambda表达式编译后的SQL语句直接运行
                //如果是转过单的订单，则获取转单之后的it信息
                //var list = db.SqlQueryable<M_DemandInfo>(
                //    @$"SELECT  [RYD_DemandList].[RYD_Company] AS [RYD_Company] , [RYD_DemandList].[RYD_DemandDetails] AS [RYD_DemandDetails] , [RYD_DemandList].[RYD_DemandId] AS [RYD_DemandId] , [RYD_DemandList].[RYD_Evaluate] AS [RYD_Evaluate] , [RYD_DemandList].[RYD_Files] AS [RYD_Files] , [RYD_DemandList].[RYD_ItEndTime] AS [RYD_ItEndTime] , [RYD_UserInfo].[RYD_Id] AS [RYD_ItId] , [RYD_UserInfo].[RYD_Name] AS [RYD_ItName] , [RYD_UserInfo].[RYD_Phone] AS [RYD_ItPhone] , [RYD_DemandList].[RYD_ItStartTime] AS [RYD_ItStartTime] , [RYD_DemandList].[RYD_KBId] AS [RYD_KBId] , [RYD_DemandList].[RYD_Level] AS [RYD_Level] , [RYD_DemandList].[RYD_Reason] AS [RYD_Reason] , [RYD_DemandList].[RYD_Solution] AS [RYD_Solution] , [RYD_DemandList].[RYD_Star] AS [RYD_Star] ,[RYD_DemandList].[RYD_State] AS [RYD_State] , [RYD_DemandList].[RYD_ToItId] AS [RYD_ToItId] , [RYD_UserInfo].[RYD_Name] AS [RYD_ToItName] , [RYD_UserInfo].[RYD_Phone] AS [RYD_ToItPhone] , [RYD_DemandList].[RYD_TypeId] AS [RYD_TypeId] , [RYD_DemandType].[RYD_DemandTypeName] AS [RYD_TypeName] , [RYD_DemandList].[RYD_UserAddress] AS [RYD_UserAddress] , [RYD_DemandList].[RYD_UserEndTime] AS [RYD_UserEndTime] , [RYD_DemandList].[RYD_UserId] AS [RYD_UserId] , [RYD_DemandList].[RYD_UserIp] AS [RYD_UserIp] , [RYD_DemandList].[RYD_UserName] AS [RYD_UserName] , [RYD_DemandList].[RYD_UserPhone] AS [RYD_UserPhone] , [RYD_DemandList].[RYD_UserStartTime] AS [RYD_UserStartTime]  
                //FROM [RYD_DemandList] RYD_DemandList  ,[RYD_UserInfo]  RYD_UserInfo ,[RYD_DemandType]  RYD_DemandType  
                //WHERE (((( [RYD_DemandList].[RYD_ItId] = [RYD_UserInfo].[RYD_Id] ) 
                //AND ( [RYD_DemandList].[RYD_ToItId] IS NULL )) 
                //OR ( [RYD_DemandList].[RYD_ToItId] = [RYD_UserInfo].[RYD_Id] )) 
                //AND ( [RYD_DemandList].[RYD_TypeId] = [RYD_DemandType].[RYD_DemandTypeNo] ))  
                //AND ( [RYD_DemandList].[RYD_DemandId] = '{RYD_DemandId}' )
                //").ToList();
                if (list.Count() > 0)
                {
                    var lists = list.Select((RYD_DemandList, RYD_UserInfo, RYD_DemandType) => new M_DemandInfo
                    {
                        RYD_Company = RYD_DemandList.RYD_Company,
                        RYD_DemandId = RYD_DemandList.RYD_DemandId,
                        RYD_DemandDetails = RYD_DemandList.RYD_DemandDetails,
                        RYD_DemandTypeName = RYD_DemandType.RYD_DemandTypeName,
                        RYD_Evaluate = RYD_DemandList.RYD_Evaluate,
                        RYD_UserId = RYD_DemandList.RYD_UserId,
                        RYD_Files = RYD_DemandList.RYD_Files,
                        RYD_ItEndTime = RYD_DemandList.RYD_ItEndTime,
                        RYD_ItId = RYD_DemandList.RYD_ItId,
                        RYD_ItStartTime = RYD_DemandList.RYD_ItStartTime,
                        RYD_KBId = RYD_DemandList.RYD_KBId,
                        RYD_Level = RYD_DemandList.RYD_Level,
                        RYD_Reason = RYD_DemandList.RYD_Reason,
                        RYD_Solution = RYD_DemandList.RYD_Solution,
                        RYD_Star = RYD_DemandList.RYD_Star,
                        RYD_State = RYD_DemandList.RYD_State,
                        RYD_UserName = RYD_DemandList.RYD_UserName,
                        RYD_UserIp = RYD_DemandList.RYD_UserIp,
                        RYD_ToItId = RYD_DemandList.RYD_ToItId,
                        RYD_UserAddress = RYD_DemandList.RYD_UserAddress,
                        RYD_UserEndTime = RYD_DemandList.RYD_UserEndTime,
                        RYD_UserPhone = RYD_DemandList.RYD_UserPhone,
                        RYD_UserStartTime = RYD_DemandList.RYD_UserStartTime,
                        RYD_Fallback = RYD_DemandList.RYD_Fallback,
                        RYD_ItName = RYD_UserInfo.RYD_Name,
                        RYD_ItPhone = RYD_UserInfo.RYD_Phone,
                        RYD_TypeId = RYD_DemandList.RYD_TypeId
                    }).First();
                    if (lists.RYD_ToItId != null)
                    {
                        var a = db.Queryable<RYD_UserInfo>().Where(res => res.RYD_Id == lists.RYD_ItId).First();
                        lists.RYD_OldItName = a.RYD_Name;
                        lists.RYD_OldItPhone = a.RYD_Phone;
                    }
                    return lists;
                }
                return new M_DemandInfo();
            }
            catch (Exception)
            {
                return new M_DemandInfo();
            }
        }

        public bool RecordDemand(M_Demand demand)
        {
            RYD_DemandList rYD_Demand = new()
            {
                RYD_UserId = demand.RYD_UserId,
                RYD_Id = Guid.NewGuid().ToString(),
                RYD_Company = demand.RYD_Company,
                RYD_Level = demand.RYD_Level,
                RYD_State = 5,
                RYD_TypeId = demand.RYD_TypeId,
                RYD_ItId = demand.RYD_ItId,
                RYD_UserStartTime = DateTime.Now,
                RYD_DemandDetails = demand.RYD_DemandDetails,
                RYD_Files = demand.RYD_Files,
                RYD_UserName = demand.RYD_UserName,
                RYD_UserPhone = demand.RYD_UserPhone,
                RYD_UserAddress = demand.RYD_UserAddress,
                RYD_UserIp = demand.RYD_UserIp,
                RYD_Reason = demand.RYD_Reason,
                RYD_Solution = demand.RYD_Solution,
                RYD_CreateTime = DateTime.Now,
                RYD_CreateBy = demand.RYD_UserId
            };
            int demandId = db.Insertable(rYD_Demand).ExecuteReturnEntity().RYD_DemandId;

            //此处加入知识库
            if (!string.IsNullOrWhiteSpace(demand.RYD_KBId) && demand.RYD_KBId == "true")
            {
                M_DemandOperate m_DemandOperate = new()
                {
                    RYD_DemandId = demandId,
                    RYD_Company = rYD_Demand.RYD_Company,
                    RYD_Evaluate = rYD_Demand.RYD_Evaluate,
                    RYD_Reason = rYD_Demand.RYD_Reason,
                    RYD_Solution = rYD_Demand.RYD_Solution,
                    RYD_UserId = rYD_Demand.RYD_UserId,
                };
                string kbId = _knowledgeBase.AddKnowledgeBase(m_DemandOperate);
                if (string.IsNullOrWhiteSpace(kbId))
                {
                    return false;
                }
                return db.Updateable<RYD_DemandList>().Where(res => res.RYD_DemandId == demandId).SetColumns(res => new RYD_DemandList { RYD_KBId = kbId }).ExecuteCommand() > 0;
            }
            return true;
            throw new NotImplementedException();
        }

        public string AddDemand2(M_Demand demand)
        {
            try
            {
                List<RYD_DemandTypeLink> typeLinks = db.Queryable<RYD_DemandTypeLink, RYD_UserInfo>((res, us) => res.RYD_UserId == us.RYD_Id)
                    .Where((res, us) =>
                        (res.RYD_Company == demand.RYD_Company || us.AcrossCompanies == 1)
                        && res.RYD_DemandTypeNo == demand.RYD_TypeId
                        && us.RYD_IsDelete == 1
                        && (us.RYD_State == 2 || (us.RYD_State == 4 && !string.IsNullOrWhiteSpace(us.RYD_Name)))
                    ).Select((res, us) => res).ToList();

                if (typeLinks.Count <= 0)
                {
                    return "";
                }
                string userId = AssignPersonnel(typeLinks);
                if (string.IsNullOrWhiteSpace(userId))
                {
                    return "";
                }
                RYD_DemandList rYD_Demand = db.Queryable<RYD_DemandList>().Where(res => res.RYD_DemandId == demand.RYD_DemandId && res.RYD_State == -2).First();

                rYD_Demand.RYD_Level = demand.RYD_Level;
                rYD_Demand.RYD_State = 1;
                rYD_Demand.RYD_TypeId = demand.RYD_TypeId;
                rYD_Demand.RYD_ItId = rYD_Demand.RYD_ToItId ?? rYD_Demand.RYD_ItId;
#pragma warning disable CS8625 // 无法将 null 字面量转换为非 null 的引用类型。
                rYD_Demand.RYD_ToItId = null;
#pragma warning restore CS8625 // 无法将 null 字面量转换为非 null 的引用类型。
                rYD_Demand.RYD_UserStartTime = DateTime.Now;
                rYD_Demand.RYD_DemandDetails = demand.RYD_DemandDetails;
                rYD_Demand.RYD_Files = demand.RYD_Files;
                rYD_Demand.RYD_UserName = demand.RYD_UserName;
                rYD_Demand.RYD_UserPhone = demand.RYD_UserPhone;
                rYD_Demand.RYD_UserAddress = demand.RYD_UserAddress;
                rYD_Demand.RYD_UserIp = demand.RYD_UserIp;
                rYD_Demand.RYD_ModifyTime = DateTime.Now;
                rYD_Demand.RYD_ModifyBy = demand.RYD_UserId;


                if (db.Updateable(rYD_Demand).ExecuteCommand() > 0)
                {
                    try
                    {
                        string wxNo = db.Queryable<RYD_UserInfo>().Where(res => res.RYD_Id == rYD_Demand.RYD_UserId && res.RYD_IsDelete == 1).First().RYD_WxNo;
                        string urlStart = AppHelper.ReadAppSettings("wxUrlStart");
                        string urlEnd = AppHelper.ReadAppSettings("wxUrlEnd");
                        string typeName = db.Queryable<RYD_DemandType>().Where(res => res.RYD_DemandTypeNo == rYD_Demand.RYD_TypeId).First().RYD_DemandTypeName;
                        string itName = db.Queryable<RYD_UserInfo>().Where(res => res.RYD_Id == rYD_Demand.RYD_ItId).First().RYD_Name;
                        string levelName = db.Queryable<RYD_FieldDict>().Where(res => res.RYD_FieldName == "DemandTypeLevel" && res.RYD_FieldValue == rYD_Demand.RYD_Level.ToString()).First().RYD_FieldText;
                        M_Template template = new()
                        {
                            client_msg_id = DateTimeOffset.Now.ToFileTime().ToString(),
                            touser = wxNo,
                            url = urlStart + "RYD_DemandId=" + rYD_Demand.RYD_DemandId + urlEnd,
                            data = new M_Template.Data()
                            {
                                first = new M_Template.valueColor()
                                {
                                    value = "重新发起提醒！"
                                },
                                keyword1 = new M_Template.valueColor()
                                {
                                    value = "下单时间：" + DateTime.Now.ToString("yyyy-MM-dd HH:mm")
                                },
                                keyword2 = new M_Template.valueColor()
                                {
                                    value = "订单单号:\t" + rYD_Demand.RYD_DemandId +
                                                "\n类别:\t" + typeName +
                                                "\nIT负责人:\t" + itName +
                                                "\n申请人:\t" + rYD_Demand.RYD_UserName +
                                                "\n事件等级:\t" + levelName
                                },
                                remark = new M_Template.valueColor()
                                {
                                    value = "请耐心等待IT人员接单！"
                                }
                            }
                        };
                        _wxMessage.SendMessage(template);
                        wxNo = db.Queryable<RYD_UserInfo>().Where(res => res.RYD_Id == rYD_Demand.RYD_ItId && res.RYD_IsDelete == 1).First().RYD_WxNo;
                        template = new M_Template()
                        {
                            state = rYD_Demand.RYD_State ?? 0,
                            demandId = rYD_Demand.RYD_DemandId,
                            client_msg_id = DateTimeOffset.Now.ToFileTime().ToString(),
                            touser = wxNo,
                            url = urlStart + "RYD_DemandId=" + rYD_Demand.RYD_DemandId + urlEnd,
                            data = new M_Template.Data()
                            {
                                first = new M_Template.valueColor()
                                {
                                    value = "订单重新发起通知！"
                                },
                                keyword1 = new M_Template.valueColor()
                                {
                                    value = "下单时间：" + DateTime.Now.ToString("yyyy-MM-dd HH:mm")
                                },
                                keyword2 = new M_Template.valueColor()
                                {
                                    value = "订单单号:\t" + rYD_Demand.RYD_DemandId +
                                                "\n类别:\t" + typeName +
                                                "\nIT负责人:\t" + itName +
                                                "\n申请人:\t" + rYD_Demand.RYD_UserName +
                                                "\n事件等级:\t" + levelName
                                },
                                remark = new M_Template.valueColor()
                                {
                                    value = "请IT人员尽快接单处理！"
                                }
                            }
                        };
                        _wxMessage.SendMessage(template);
                        QuartzNetJob.QuartzHelper q = new();
                        int minutes = 15;
                        var levelMinutes = db.Queryable<RYD_FieldDict>().Where(res => res.RYD_FieldName == "DemandTypeLevel" && res.RYD_FieldValue == rYD_Demand.RYD_Level.ToString() && res.RYD_State == 1).ToList().FirstOrDefault();
                        if (levelMinutes != null)
                        {
                            minutes = Convert.ToInt32(levelMinutes.RYD_Remark);
                        }
                        q.SetIntervalJob<JobWork.JobSendMessage>(minutes, template, rYD_Demand.RYD_DemandId + "");


                    }
                    catch (Exception)
                    {
                    }
                    return userId;
                }
                return "";
            }
            catch (Exception)
            {
                return "";
            }

        }

        public bool SetLevelOrder(RYD_DemandList rYD_DemandList)
        {
            try
            {
                var demand = db.Queryable<RYD_DemandList>().Where(res => res.RYD_DemandId == rYD_DemandList.RYD_DemandId && res.RYD_State == 1).First();
                demand.RYD_Level = rYD_DemandList.RYD_Level;
                demand.RYD_ModifyBy = rYD_DemandList.RYD_ItId;
                demand.RYD_ModifyTime = DateTime.Now;

                if (db.Updateable(demand).ExecuteCommand() > 0)
                {
                    new QuartzNetJob.QuartzHelper().RemoveJob(demand.RYD_DemandId + "");

                    var userInfo = db.Queryable<RYD_UserInfo>().Where(res => res.RYD_Id == demand.RYD_UserId).First();
                    var itUserInfo = db.Queryable<RYD_UserInfo>().Where(res => res.RYD_Id == (demand.RYD_ToItId ?? demand.RYD_ItId)).First();
                    string urlStart = AppHelper.ReadAppSettings("wxUrlStart");
                    string urlEnd = AppHelper.ReadAppSettings("wxUrlEnd");
                    string typeName = db.Queryable<RYD_DemandType>().Where(res => res.RYD_DemandTypeNo == demand.RYD_TypeId).First().RYD_DemandTypeName;
                    string levelName = db.Queryable<RYD_FieldDict>().Where(res => res.RYD_FieldName == "DemandTypeLevel" && res.RYD_FieldValue == demand.RYD_Level.ToString()).First().RYD_FieldText;
                    M_Template template = new()
                    {
                        client_msg_id = DateTimeOffset.Now.ToFileTime().ToString(),
                        touser = userInfo.RYD_WxNo,
                        url = urlStart + urlEnd,
                        data = new M_Template.Data()
                        {
                            first = new M_Template.valueColor()
                            {
                                value = "订单级别修改提醒！"
                            },
                            keyword1 = new M_Template.valueColor()
                            {
                                value = "修改时间：" + DateTime.Now.ToString("yyyy-MM-dd HH:mm")
                            },
                            keyword2 = new M_Template.valueColor()
                            {
                                value = "订单单号:\t" + demand.RYD_DemandId +
                                                "\n类别:\t" + typeName +
                                                "\nIT负责人:\t" + itUserInfo.RYD_Name +
                                                "\n申请人:\t" + demand.RYD_UserName +
                                                "\n事件等级:\t" + levelName
                            },
                            remark = new M_Template.valueColor()
                            {
                                value = "IT负责人已重新评估需求级别，请注意！"
                            }
                        }
                    };
                    _wxMessage.SendMessage(template);
                    template = new M_Template()
                    {
                        client_msg_id = DateTimeOffset.Now.ToFileTime().ToString(),
                        touser = itUserInfo.RYD_WxNo,
                        url = urlStart + "RYD_DemandId=" + demand.RYD_DemandId + urlEnd,
                        data = new M_Template.Data()
                        {
                            first = new M_Template.valueColor()
                            {
                                value = "订单级别修改提醒！"
                            },
                            keyword1 = new M_Template.valueColor()
                            {
                                value = "修改时间：" + DateTime.Now.ToString("yyyy-MM-dd HH:mm")
                            },
                            keyword2 = new M_Template.valueColor()
                            {
                                value = "订单单号:\t" + demand.RYD_DemandId +
                                                "\n类别:\t" + typeName +
                                                "\nIT负责人:\t" + itUserInfo.RYD_Name +
                                                "\n申请人:\t" + demand.RYD_UserName +
                                                "\n事件等级:\t" + levelName
                            },
                            remark = new M_Template.valueColor()
                            {
                                value = "已重新修改订单级别！ "
                            }
                        }
                    };
                    _wxMessage.SendMessage(template);
                    QuartzNetJob.QuartzHelper q = new();
                    int minutes = 15;
                    var levelMinutes = db.Queryable<RYD_FieldDict>().Where(res => res.RYD_FieldName == "DemandTypeLevel" && res.RYD_FieldValue == demand.RYD_Level.ToString() && res.RYD_State == 1).ToList().FirstOrDefault();
                    if (levelMinutes != null)
                    {
                        minutes = Convert.ToInt32(levelMinutes.RYD_Remark);
                    }
                    q.SetIntervalJob<JobWork.JobSendMessage>(minutes, template, demand.RYD_DemandId + "");
                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch (Exception)
            {

                throw;
            }
            throw new NotImplementedException();
        }

        public RYD_DemandList QueryLastDemand(string RYD_Id)
        {
            return db.Queryable<RYD_DemandList>().Where(res => res.RYD_UserId == RYD_Id && res.RYD_State > 0 && res.RYD_State != 5).OrderByDescending(res => res.RYD_UserStartTime).First();
        }

        public bool OtherCompanyDemandNum(M_DemandList demandList)
        {
            return db.Queryable<RYD_DemandList>()
                    .Where(res => res.RYD_Company != demandList.RYD_Company
                        &&
                        (
                            res.RYD_State > 0 && res.RYD_State < 3
                            && (
                                (res.RYD_ItId == demandList.RYD_UserId && res.RYD_ToItId == null)
                                || res.RYD_ToItId == demandList.RYD_UserId
                                || res.RYD_UserId == demandList.RYD_UserId
                            )
                        )
                    ).Count() > 0;
        }
    }
}
